﻿// AGatherManager.cs is part of AGatherBot.
//
// AGatherBot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 3 as
// published by the Free Software Foundation.
//
// AGatherBot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public version 2 License for more details.
//
// You should have received a copy of the GNU General Public License
// along with AGatherBot. If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;

namespace AGatherBot
{
    public class AGatherManager : IPartImportsSatisfiedNotification
    {
        #region Properties

        public SortedDictionary<string, IChatCommand>       ChatCommands { get; private set; }
        public SortedDictionary<string, IGameServerCommand> GameServerCommands { get; private set; }

        /// <summary>
        /// Gets or sets the chat client.
        /// </summary>
        [Import]
        public IChatClient ChatClient { get; protected set; }

        /// <summary>
        /// Gets or sets the game server.
        /// </summary>
        [Import]
        public IGameServersManager GameServersManager { get; protected set; }

        /// <summary>
        /// Gets or sets the account system.
        /// </summary>
        [Import]
        public IAccountSystem AccountSystem { get; protected set; }

        /// <summary>
        /// Gets the gathers
        /// </summary>
        public Dictionary<int, AGather> Gathers { get; protected set; }

        #endregion

        #region Constructor

        public AGatherManager()
        {
            this.ChatCommands       = new SortedDictionary<string, IChatCommand>(StringComparer.OrdinalIgnoreCase);
            this.GameServerCommands = new SortedDictionary<string, IGameServerCommand>(StringComparer.OrdinalIgnoreCase);
            this.Gathers            = new Dictionary<int, AGather>();
        }

        #endregion

        #region Methods

        #region Commands

        public void RegisterGameServerCommand(IGameServerCommand cmd)
        {
            if (this.GameServerCommands.ContainsKey(cmd.CommandName))
            {
                throw new ArgumentException("Command already exists.");
            }

            if (cmd.CommandName.IndexOfAny(Program.ForbiddenCommandChars) != -1)
            {
                throw new ArgumentException("Invalid command name.");
            }

            lock (this.GameServerCommands)
            {
                this.GameServerCommands.Add(cmd.CommandName, cmd);
            }
        }

        public void RegisterChatCommand(IChatCommand cmd)
        {
            if (this.ChatCommands.ContainsKey(cmd.CommandName))
            {
                throw new ArgumentException("Command already exists.");
            }

            if (cmd.CommandName.IndexOfAny(Program.ForbiddenCommandChars) != -1)
            {
                throw new ArgumentException("Invalid command name.");
            }

            lock (this.ChatCommands)
            {
                this.ChatCommands.Add(cmd.CommandName, cmd);
            }
        }

        /// <summary>
        /// Update the commands in the command collection.
        /// </summary>
        private void UpdateCommands()
        {
            //UpdateCommand(new AGatherBot.Commands.ExitCommand());
            //UpdateCommand(new AGatherBot.Commands.HelpCommand());
            //UpdateCommand(new AGatherBot.Commands.ExecFileCommand());
        }

        private void UpdateChatCommand(IChatCommand cmd)
        {
            if (this.ChatCommands.ContainsKey(cmd.CommandName))
            {
                this.ChatCommands.Remove(cmd.CommandName);
            }

            this.RegisterChatCommand(cmd);
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        public void OnImportsSatisfied()
        {
            this.ChatClient.Parent = this;
            // TODO: Make sure this is not double-registered?
            this.ChatClient.OnPrivateMessage += (s, e) => this.ChatClient_ExecuteMessage(s, e, ChatTarget.Private);
            this.ChatClient.OnChannelMessage += (s, e) => this.ChatClient_ExecuteMessage(s, e, ChatTarget.Channel);
        }

        // TODO: What are we doing with multiple chars?
        private void ChatClient_ExecuteMessage(object sender, ChatMessageEventArgs e, ChatTarget location)
        {
            // If the given input is nothing, do nothing.
            if (string.IsNullOrWhiteSpace(e.Text))
            {
                return;
            }

            var text = e.Text.Trim();

            // Extract the command name.
            var command = text.Split()[0];

            // TODO: Check permissions

            // If command was found, execute it whilst giving it the input as a parameter.
            if ((this.ChatCommands.ContainsKey(command)) && (this.ChatCommands[command].WorkingTarget == location))
            {
                //this.ChatCommands[command].Execute(source, text, location);
            }
        }

        #endregion
    }
}
